﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SlimDX.DirectInput;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;
using Microsoft.Win32;

namespace JoystickApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            GetSticks();
            Sticks = GetSticks();
            timer1.Enabled = true;
            Thread thread = new Thread(new ThreadStart(RecivebyUDP));
            thread.IsBackground = true;
            thread.Start(); ;
           // WallpaperHelper.ChangeWallPaper("http://121.37.249.223/guzhuang/img/mom-ha-20-2%20(3).jpg");
        }
        //UDP接受 
        public void RecivebyUDP()
        {
            UdpClient client = null;
            byte[] receiveData = null;
            //实例化一个远程端点，IP和端口可以随意指定，等调用client.Receive(ref remotePoint)时会将该端点改成真正发送端端点 
            IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);
            while (true)
            {
                client = new UdpClient(8400);
                receiveData = client.Receive(ref remotePoint);//接收数据 

                try
                {
                    string datastring = Encoding.GetEncoding("gb2312").GetString(receiveData);
                    MethodInvoker methodInvoker = new MethodInvoker(() => { SendKeys.Send(datastring); });
                    Invoke(methodInvoker);

                }
                catch (Exception e)
                {


                }

                client.Close();//关闭连接 
                Thread.Sleep(100);
            }
        }

        DirectInput Input = new DirectInput();
        SlimDX.DirectInput.Joystick stick;
        Joystick[] Sticks;
        bool MouseClicked = false;

        int yValue = 0;
        int xValue = 0;
        int zValue = 0;
        int rzValue = 0;
        #region 鼠标接口 获取鼠标
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern void mouse_event(uint flag, uint _x, uint _y, uint btn, uint exInfo);
        private const int MOUSEEVENT_LEFTDOWN = 0x02;
        private const int MOUSEEVENT_LEFTUP = 0x04;
        public Joystick[] GetSticks()
        {
            List<SlimDX.DirectInput.Joystick> sticks = new List<SlimDX.DirectInput.Joystick>();
            foreach(DeviceInstance device in Input.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
            {
                try
                {
                    stick = new SlimDX.DirectInput.Joystick(Input, device.InstanceGuid);
                    stick.Acquire();

                    foreach (DeviceObjectInstance deviceObject in stick.GetObjects())
                    {
                        if((deviceObject.ObjectType & ObjectDeviceType.Axis) != 0)
                        {
                            stick.GetObjectPropertiesById((int)deviceObject.ObjectType).SetRange(-100,100);
                        }
                    }
                    sticks.Add(stick);
                }
                catch (DirectInputException)
                {

                    
                }
            }
            return sticks.ToArray();
        }
        #endregion
        void stickHandle(Joystick stick, int id)
        {
            JoystickState state = new JoystickState();
            state = stick.GetCurrentState();       
            yValue = state.Y;
            xValue = state.X;
            zValue = state.Z;
            rzValue = state.RotationZ;
          //  MouseMove(xValue, yValue);
            label2.Text = state.X.ToString();
            label3.Text = state.Y.ToString();        
            mouse_event(0x0800, 0, 0, (uint)rzValue, 0);
            FlagY(zValue,rzValue);
            bool[] buttons = state.GetButtons();
            for (int i = 0; i < 16; i++)
            {
                if (buttons[i])
                {
                    Get(i);
                    label1.Text = "button " + i.ToString() + " " + buttons[i].ToString();
                }
            }
      
         //方向键
            int[] ss3 = state.GetPointOfViewControllers();
            label4.Text = ss3[0].ToString();
            Flags(ss3[0]);
        }
        /// <summary>
        /// 摇杆
        /// </summary>
        /// <param name="i"></param>
        public void FlagY(int j,int i)
        {
            if (i == 100)
            {

            }
            else if (i == -100) { 
            
            }
            if (j == 100)//右摇杆右
            {
                SendKeys.Send(GetEnumDescription(CMD.视频_快进));

            }
            else if (j == -100) {
                SendKeys.Send(GetEnumDescription(CMD.视频_后退));

            }
        }
            /// <summary>
            /// 方向
            /// </summary>
            /// <param name="i"></param>
            public void Flags(int i)
        {
            if (i == 200) { 
            
            }
            if (i ==18000)//下
            {

                SendKeys.Send(GetEnumDescription(CMD.B站_声音小));
                SendKeys.Send(GetEnumDescription(CMD.视频_声音小));

            }
            if (i == 0)//上
            {
                SendKeys.Send(GetEnumDescription(CMD.B站_声音大));
                SendKeys.Send(GetEnumDescription(CMD.视频_声音大));

            }
            if (i == 27000)//左
            {
                SendKeys.Send(GetEnumDescription(CMD.视频_快进));
                
            }

            if (i == 9000)//右
            {
                SendKeys.Send(GetEnumDescription(CMD.视频_后退));

            }
        }
        /// <summary>
        /// 按键
        /// </summary>
        /// <param name="i"></param>
        public void Get(int i) {
            if (i == (int)ACTIOM.X) {
                Cmd(10, GetEnumDescription(CMD.B站_弹幕));
                Cmd(10, GetEnumDescription(CMD.触发Enter));
                mouse_event(MOUSEEVENT_LEFTDOWN, 0, 0, 0, 0);
                mouse_event(MOUSEEVENT_LEFTUP, 0, 0, 0, 0);
            }
            if (i == (int)ACTIOM.A)
            {
                Cmd(1, GetEnumDescription(CMD.视频_暂停开始));

            }
            if (i == (int)ACTIOM.Y)
            {
                Cmd(1, GetEnumDescription(CMD.视频_全屏));

            }
            if (i == (int)ACTIOM.B)
            {
                Cmd(2, GetEnumDescription(CMD.网页静音));

            }
            if (i == (int)ACTIOM.RB) {
                Cmd(2, GetEnumDescription(CMD.B站_下一集));

            }
        }
        int isrun = 0;
        public void Cmd(int speed, string cmd)
        {
            isrun++;
            if (isrun > speed)
            {
                SendKeys.Send(cmd);
                isrun = 0;
            }
        }
        public enum ACTIOM
        {
            A = 0,
            B = 1,
            MouseLeftUp = 2,
            X = 3,
            Y = 4,
            MouseMiddleDown = 5,
            LB = 6,
            RB = 7,
            LT = 8,
            RT = 9,
            BACK = 10,
            STACK = 11,
            HOME = 12

        }
        /// <summary>
        /// 基础通信
        /// </summary>
        [Flags]

        public enum CMD
        {
            /// <summary>
            /// 未知指令测试用
            /// </summary>
            [Description("未知指令测试用")]

            未知指令,

            /// <summary>
            /// 关机指令
            /// </summary>
            [Description("关机指令")]

            关机,

            /// <summary>
            /// 锁定电脑指令暂未实现
            /// </summary>
            [Description("锁定电脑指令暂未实现")]

            锁定,

            /// <summary>
            /// 重启电脑指令
            /// </summary>
            [Description("重启电脑指令")]
            重启,

            /// <summary>
            /// 电脑休眠指令
            /// </summary>
            [Description("电脑休眠指令")]
            休眠,

            /// <summary>
            /// 电脑睡眠指令
            /// </summary>
            [Description("电脑睡眠指令")]
            睡眠,
            /// <summary>
            /// 注销指令
            /// </summary>
            [Description("注销指令")]
            注销,
            /// <summary>
            /// B站弹幕
            /// </summary>
            [Description("d")]
            B站_弹幕,
            /// <summary>
            /// 视频_全屏
            /// </summary>
            [Description("f")]
            视频_全屏,
            /// <summary>
            /// 回车
            /// </summary>
            [Description("~")]
            触发Enter,
            /// <summary>
            /// 视频_暂停开始
            /// </summary>
            [Description(" ")]
            视频_暂停开始,
            /// <summary>
            /// 视频_快进
            /// </summary>
            [Description("{RIGHT}")]
            视频_快进,
            /// <summary>
            /// 视频_后退
            /// </summary>
            [Description("{LEFT}")]
            视频_后退,
            /// <summary>
            /// B站_声音大
            /// </summary>
            [Description("{UP}")]
            B站_声音大,
            /// <summary>
            /// B站_声音小
            /// </summary>
            [Description("{DOWN}")]
            B站_声音小,
            /// <summary>
            /// B站_下一集
            /// </summary>
            [Description("]")]
            B站_下一集,
            /// <summary>
            /// 视频_声音大
            /// </summary>
            [Description("^%{UP}")]
            视频_声音大,
            /// <summary>
            /// 视频_声音小
            /// </summary>
            [Description("^%{DOWN}")]
            视频_声音小,
            /// <summary>
            /// 网页静音
            /// </summary>
            [Description("%l")]
            网页静音,
            /// <summary>
            /// 切换浏览器页面
            /// </summary>
            [Description("^{TAB}")]
            切换浏览器页面

        }
        #region
        /// <summary>
        /// 更换壁纸
        /// </summary>
        public class WallpaperHelper
        {
            [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
            public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

            /// <summary>
            /// 更换壁纸
            /// </summary>
            /// <param name="fileName">壁纸文件的路径</param>
            /// <returns>操作结果：true为更换成功，false为更换失败</returns>
            public static bool ChangeWallPaper(string fileName)
            {
                if (string.IsNullOrEmpty(fileName))
                {
                    return false;
                }
                if (File.Exists(fileName) == false)
                {
                   // return false;
                }

               // fileName = Path.GetFullPath(fileName);
                var nResult = SystemParametersInfo(0x0073, 200, fileName, 0x1 | 0x2); //更换壁纸
                if (nResult == 0)
                {
                    return false;
                }
                else
                {
                    RegistryKey hk = Registry.CurrentUser;
                    RegistryKey run = hk.CreateSubKey(@"Control Panel\Desktop\");
                    run.SetValue("Wallpaper", fileName);

                    return true;
                }
            }
        }
    #endregion
    #region
    public string GetEnumDescription(Enum enumValue)
        {
            string value = enumValue.ToString();
            FieldInfo field = enumValue.GetType().GetField(value);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);  //获取描述属性
            if (objs == null || objs.Length == 0)  //当描述属性没有时，直接返回名称
                return value;
            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }
        public void MouseMove(int posx, int posy)
        {
            Cursor.Position = new Point(Cursor.Position.X + posx, Cursor.Position.Y + posy);
            Cursor.Clip = new Rectangle(this.Location, this.Size);
        }
        private void Timer1_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < Sticks.Length; i++)
            {
                stickHandle(Sticks[i], i);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Joystick[] joystick = GetSticks();
        }
        #endregion
    }
}
